package com.yc.boot.common.model.response;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 返回数据封装实现类
 *
 * @param <T> 特别说明：不指定泛型类型时，表示data无返回值
 * @author 杨智杰
 */

/*这个T表示派生自Object类的任何类，(泛型类)比如String,Integer,Double等等。这里要注意的是，T一定是
   派生于Object类的。为方便起见，大家可以在这里把T当成String,即String在类中怎么用，那T在类中就可以怎么用
  在原来的T后面用逗号隔开，写上其它的任意大写字母即可。想加几个就加几个，比如我们想加五个泛型变量，
   那应该是这样的：class MorePoint<T,U,A,B,C>{
  }
    上面我们的函数中，返回值都是void，但现实中不可能都是void，
    有时，我们需要将泛型变量返回，比如下面这个函数：

    public static List<SuccessModel> parseArray(String response){
    List<SuccessModel> modelList = JSON.parseArray(response, SuccessModel.class);
    return modelList;
}

    E — Element，常用在java Collection里，如：List<E>,Iterator<E>,Set<E>
   K,V — Key，Value，代表Map的键值对
   N — Number，数字
 T — Type，类型，如String，Integer等等 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "业务层-返回数据封装")
public class Outcome<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    @ApiModelProperty(value = "状态码，-1操作失败，200操作成功，具体请参考提示消息", required = true)
    private int code;

    /**
     * 提示消息
     */
    @ApiModelProperty(value = "提示消息", required = true)
    private String message;

    /**
     * 业务数据
     */
    @ApiModelProperty(value = "业务数据")
    private T data;

    public Outcome(Result.Status status) {
        this(status.getCode(), status.getMessage());
    }

    public Outcome(Result.Status status, String message) {
        this(status.getCode(), message, null);
    }

    public Outcome(Result.Status status, String message, T data) {
        this(status.getCode(), message, data);
    }

    public Outcome(Result.Status status, T data) {
        this(status.getCode(), status.getMessage(), data);
    }

    public Outcome(int code, String message) {
        this(code, message, null);
    }

    /**
     * 默认成功
     *
     * @return Outcome
     */
    public static Outcome success() {
        return new Outcome(DefaultStatus.SUCCESS);
    }

    /**
     * 成功返回结果
     *
     * @param message
     * @return Outcome
     */
    public static Outcome success(String message) {
        return new Outcome(DefaultStatus.SUCCESS, message);
    }

    /**
     * 成功返回结果
     *
     * @param status
     * @return Outcome
     */
    public static Outcome success(Result.Status status) {
        return new Outcome(status);
    }

    /**
     * 成功返回结果
     *
     * @param status
     * @param message
     * @return Outcome
     */
    public static Outcome success(Result.Status status, String message) {
        return new Outcome(status, message);
    }

    /**
     * 成功返回结果
     *
     * @param data
     * @return Outcome
     */
    public static <E> Outcome<E> success(E data) {
        return new Outcome<E>(DefaultStatus.SUCCESS, data);
    }

    /**
     * 成功返回结果
     *
     * @param message
     * @param data
     * @return Outcome
     */
    public static <E> Outcome<E> success(String message, E data) {
        return new Outcome<E>(DefaultStatus.SUCCESS, message, data);
    }

    /**
     * 成功返回结果
     *
     * @param code
     * @param message
     * @param data
     * @return Outcome
     */
    public static <E> Outcome<E> success(int code, String message, E data) {
        return new Outcome<E>(code, message, data);
    }

    /**
     * 返回自定义结果
     *
     * @param code
     * @param message
     * @param data
     * @param <Object>
     * @return
     */
    public static <Object> Outcome<Object> successful(int code, String message, Object data) {
        return new Outcome<Object>(code, message, data);
    }

    /**
     * 默认失败
     *
     * @return Outcome
     */
    public static Outcome failure() {
        return new Outcome(DefaultStatus.FAILURE);
    }

    /**
     * 根据错误消息构建
     *
     * @param message
     * @return Outcome
     */
    public static Outcome failure(String message) {
        return new Outcome(DefaultStatus.FAILURE, message);
    }

    /**
     * 根据错误消息构建
     *
     * @param code
     * @param message
     * @return Outcome
     */
    public static Outcome failure(int code, String message) {
        return new Outcome(code, message);
    }

    /**
     * 根据状态码
     *
     * @param status
     * @return Outcome
     */
    public static Outcome failure(Result.Status status) {
        return new Outcome(status);
    }

    /**
     * 根据错误消息构建
     *
     * @param status
     * @param message
     * @return Outcome
     */
    public static Outcome failure(Result.Status status, String message) {
        return new Outcome(status.getCode(), message, null);
    }

    /**
     * 根据错误信息构建
     *
     * @param message
     * @param data
     * @return Outcome
     */
    public static <E> Outcome<E> failure(String message, E data) {
        return new Outcome(DefaultStatus.FAILURE, message, data);
    }


    /**
     * 根据错误信息构建
     *
     * @param status
     * @param message
     * @param data
     * @return Outcome
     */
    public static <E> Outcome<E> failure(Result.Status status, String message, E data) {
        return new Outcome(status, message, data);
    }

    /**
     * 根据状态判断是否成功
     *
     * @param status
     * @return Outcome
     */
    public static Outcome status(boolean status) {
        return status ? success() : failure();
    }

}